#ifndef __IMP_VIDEO_COMMON_H__
#define __IMP_VIDEO_COMMON_H__
#include <stdint.h>
#include <semaphore.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef void* AL_MUTEX;
typedef void* AL_SEMAPHORE;
typedef void* AL_EVENT;
#define AL_NO_WAIT 0
#define AL_WAIT_FOREVER 0xFFFFFFFF

typedef struct {
	pthread_mutex_t Mutex;
	pthread_cond_t Cond;
	bool bSignaled;
} evt_t;

typedef struct
{
	size_t m_zMaxElem;
	size_t m_zTail;
	size_t m_zHead;
	void** m_ElemBuffer;
	AL_MUTEX hMutex;
	AL_EVENT hEvent;
	int m_iBufNumber;
	bool m_isDecommited;
	AL_SEMAPHORE hSpaceSem;
} App_Fifo;

typedef struct imp_video_list imp_video_list_t;
struct imp_video_list {
	imp_video_list_t	*prev;
	imp_video_list_t	*next;
};

typedef struct imp_video_list_elem {
	imp_video_list_t		list;
	void					*data;
	uint32_t				dataSize;
	void (*free_data)(void *data);
} imp_video_list_elem_t;

typedef struct imp_video_list_queue {
	pthread_mutex_t			mutex;
	imp_video_list_t		queue;
} imp_video_list_queue_t;

typedef struct imp_video_container {
	imp_video_list_queue_t		freeListQueue;
	imp_video_list_queue_t		busyListQueue;
	imp_video_list_queue_t		doneListQueue;
	imp_video_list_elem_t		*pelem;
	uint32_t					pelemCnt;
} imp_video_container_t;

extern void *video_vbm_malloc(int index, int size, int align);
extern void video_vbm_free(int index, void *vaddr);
extern intptr_t video_vbm_virt_to_phys(intptr_t vaddr);
extern intptr_t video_vbm_phys_to_virt(intptr_t paddr);
extern int video_sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
extern void imp_video_push_queue_head(imp_video_list_queue_t *list_queue, imp_video_list_t *head, imp_video_list_t *list);
extern void imp_video_push_queue_tail(imp_video_list_queue_t *list_queue, imp_video_list_t *head, imp_video_list_t *list);
extern void imp_video_pop_queue(imp_video_list_queue_t *list_queue, imp_video_list_t *head, imp_video_list_t **list);
extern imp_video_container_t *imp_video_container_init(uint32_t elem_num, uint32_t elem_data_size);
extern void imp_video_container_deinit(imp_video_container_t *pcontainer);
bool Fifo_Init(App_Fifo* pFifo, size_t zMaxElem);
void Fifo_Deinit(App_Fifo* pFifo);
bool Fifo_Queue(App_Fifo* pFifo, void* pElem, uint32_t uWait);
void* Fifo_Dequeue(App_Fifo* pFifo, uint32_t uWait);

#ifdef __cplusplus
}
#endif

#endif
